const { Component } = React;

class VirtualList extends Component {
  constructor(props) {
    super(props);
    this.container = React.createRef();
    this.extraItemNumber = 2;
    this.state = {
      containerScrollTop: 0
    };
  }

  handleContainerScroll = e => {
    this.setState({
      containerScrollTop: this.container.current.scrollTop
    });
  };

  getVirtualList() {
    const { extraItemNumber, state, props } = this;
    const { containerScrollTop } = state;
    const { itemHeight, children, containerHeight } = props;
    let firstIndex = Math.floor(containerScrollTop / itemHeight);
    let lastIndex = firstIndex + Math.ceil(containerHeight / itemHeight);
    firstIndex = Math.max(firstIndex - extraItemNumber, 0);
    lastIndex = Math.min(lastIndex + extraItemNumber, children.length);
    const arr = [];
    for (let i = firstIndex; i < lastIndex; i++) {
      arr.push(children[i]);
    }
    return {
      arr,
      top: firstIndex * itemHeight
    };
  }

  render() {
    const { itemHeight, containerHeight, children } = this.props;
    const len = children.length;
    const { arr, top } = this.getVirtualList();

    return (
      <div
        style={{ height: `${containerHeight}px` }}
        className="container"
        ref={this.container}
        onScroll={() => this.handleContainerScroll()}
      >
        <div
          className="holder"
          style={{
            height: itemHeight * len + "px"
          }}
        />
        <div
          className="content"
          style={{
            top: `${top}px`
          }}
        >
          {arr}
        </div>
      </div>
    );
  }
}

class CoinWinner extends Component {
  constructor(props) {
    super(props);
    this.state = {
      members: [],
      memberCount: 1000,
      isOver: false,
      youWish: 1
    };
  }

  componentDidMount() {
    this.handleChangeMemberCount();
  }

  shouldComponentUpdate(nextProps, nextState) {
    return true;
  }

  handleChangeMemberCount = () => {
    const { memberCount: count } = this.state;
    const newMembers = [];
    for (let index = 1; index <= count; index++) {
      let member = {
        id: index,
        name: `玩家 ${index}`,
        winCount: 0
      };
      newMembers.push(member);
    }
    this.setState({ members: newMembers, isOver: false });
  };

  handleThrowCoin = () => {
    const { members, isOver, youWish } = this.state;
    if (isOver) {
      alert("游戏结束，请点击变更人数开始新的一轮");
      return;
    }

    let newMembers = [];
    for (const member of members) {
      //如果是正面才进入下一轮
      if (this.isFront()) {
        newMembers.push(
          Object.assign({}, member, { winCount: member.winCount + 1 })
        );
      }
    }
    if (newMembers.length === 0) {
      if (members.some(m => m.index === youWish)) {
        alert("您很幸运到了最后");
      } else {
        alert("您被淘汰了呢");
      }
      alert("游戏结束，剩下的都是百年难遇的幸运儿");
      this.setState({ isOver: true });
    } else {
      this.setState({ members: newMembers });
    }
  };

  isFront = () => {
    let ran = Math.ceil(Math.random() * 10);
    //如果随机数在1-5（包含5），就认为是正面，在6-10
    return ran < 6;
  };

  render() {
    const { memberCount, members, youWish } = this.state;
    const virtualListProps = {
      itemHeight: 22,
      containerHeight: 500,
    };

    const memeberDoms = members.map(m => (
      <div className="member" key={m.id}>
        [{m.name}]-[{m.winCount}次]
      </div>
    ));
    
    return (
      <div>
        <div>
          <input
            type="number"
            step="10"
            min="10"
            max="50000"
            value={memberCount}
            onChange={e => this.setState({ memberCount: e.target.value })}
          />
          <input
            type="button"
            style={{ marginLeft: 10 }}
            onClick={() => this.handleChangeMemberCount()}
            value="更改人数"
          />
          <input
            type="button"
            style={{ marginLeft: 10 }}
            onClick={() => this.handleThrowCoin()}
            value="投掷硬币"
          />
          <span style={{ marginLeft: 10 }}>剩余玩家人数：{members.length}</span>
          <span style={{ marginLeft: 10 }}>
            你想当的玩家编号：
            <input
              type="number"
              min="1"
              max={members.length + 1}
              value={youWish}
              onChange={e => this.setState({ youWish: e.target.value })}
            />
          </span>
        </div>
        <div style={{ color: "red" }}>投掷硬币为正面的玩家进入下一轮</div>
        <VirtualList {...virtualListProps}>{memeberDoms}</VirtualList>
      </div>
    );
  }
}

class App extends Component {
  render() {
    return <CoinWinner />;
  }
}
ReactDOM.render(<App />, document.getElementById("root"));
